/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.beautycenter.ModelosTabela;

import br.com.beautycenter.Funcionalidades.Data;
import br.com.beautycenter.DAO.PersisteSessao;
import br.com.beautycenter.bean.Funcionario;
import br.com.beautycenter.bean.Sessao;
import br.com.beautycenter.bean.Tratamento;
import java.awt.BorderLayout;
import java.awt.Color;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.table.AbstractTableModel;
import org.joda.time.DateTime;
import org.joda.time.DateTimeConstants;
import org.joda.time.Days;

/**
 *
 * @author JoãoVictor
 */
public class TableModelAgenda extends AbstractTableModel {

    PersisteSessao persisteSessao = new PersisteSessao();
    Funcionario funcionario;
    DateTime[] semana = new DateTime[6];
    List<JPanel[]> conteudo = new ArrayList<JPanel[]>();
    String[] dias = {"Segunda-Feira", "Terça-Feira", "Quarta-Feira","Quinta-Feira", "Sexta-Feira", "Sábado"};
    
    public TableModelAgenda(Funcionario funcionario, Date data) {
        preencherListaConteudo();
        
        if(funcionario == null || data == null) return;
        this.funcionario = funcionario;
    }
    
    public void preencherColuna(Date data){
        DateTime d = new DateTime(data.getTime());
        
        //pega os dia da semana de uma determinada data (dias de segunda a sábado)
        semana[0] = d.withDayOfWeek(DateTimeConstants.MONDAY);
        semana[0] = new DateTime(semana[0].year().get(), semana[0].monthOfYear().get(), semana[0].dayOfMonth().get(), 0, 0, 0);
        
        semana[1] = d.withDayOfWeek(DateTimeConstants.TUESDAY);
        semana[1] = new DateTime(semana[1].year().get(), semana[1].monthOfYear().get(), semana[1].dayOfMonth().get(), 0, 0, 0);
        
        semana[2] = d.withDayOfWeek(DateTimeConstants.WEDNESDAY);
        semana[2] = new DateTime(semana[2].year().get(), semana[2].monthOfYear().get(), semana[2].dayOfMonth().get(), 0, 0, 0);
        
        semana[3] = d.withDayOfWeek(DateTimeConstants.THURSDAY);
        semana[3] = new DateTime(semana[3].year().get(), semana[3].monthOfYear().get(), semana[3].dayOfMonth().get(), 0, 0, 0);
        
        semana[4] = d.withDayOfWeek(DateTimeConstants.FRIDAY);
        semana[4] = new DateTime(semana[4].year().get(), semana[4].monthOfYear().get(), semana[4].dayOfMonth().get(), 0, 0, 0);
        
        semana[5] = d.withDayOfWeek(DateTimeConstants.SATURDAY);
        semana[5] = new DateTime(semana[5].year().get(), semana[5].monthOfYear().get(), semana[5].dayOfMonth().get(), 0, 0, 0);
        
        for(int i=0; i<semana.length; i++){
            colunas[i+1] = dias[i].concat(" - " + Data.formatoDataConvencional.format(semana[i].toDate()));
        }
        
        /**
         * DateTime sabado = d.withDayOfWeek(DateTimeConstants.SATURUDAY)
         * if(Days.daysBetween(d,sabado).getDays == 0) //é sabado
         */
    }

    public void setFuncionario(Funcionario funcionario) {
        this.funcionario = funcionario;
    }
    
    public void preencherListaConteudo(){
        try {
            conteudo.clear();
            Date hora = Data.horaSimpels.parse("08:00");
            DateTime dt = new DateTime(hora.getTime());
            DateFormat format = DateFormat.getTimeInstance(DateFormat.SHORT, new Locale("pt", "BR"));
            for(int i=0; i<12; i++){
                JPanel[] temp = new JPanel[7];
                
                for(int j=0; j<7; j++){
                    temp[j] = new JPanel(new BorderLayout());
                    
                    //cada jpanel,com exceção os da primeira coluna, terão 2 graphics, onde cada uma representará 30 min.
                    if(j==0){
                        Date aux = new Date(dt.getMillis());
                        JLabel horaAux = new JLabel(format.format(aux));
                        horaAux.setHorizontalAlignment(JLabel.CENTER);
                        

                        temp[0].add(horaAux, BorderLayout.CENTER);
                    }
                }
                
                conteudo.add(temp);
                dt = dt.plusHours(1);
            }
            
        } catch (ParseException ex) {
            ex.printStackTrace();
            System.out.println("erro:");
        }
    }
    
    private String[] colunas = {"Horário","Segunda-Feira", "Terça-Feira", "Quarta-Feira", "Quinta-Feira",
                                "Sexta-Feira", "Sábado"};

    public String[] getColunas() {
        return colunas;
    }
    
    private static final int HORARIO = 0;
    private static final int SEGUNDA = 1;
    private static final int TERCA = 2;
    private static final int QUARTA = 3;
    private static final int QUINTA = 4;
    private static final int SEXTA = 5;
    private static final int SABADO = 6;
    
    @Override
    public int getRowCount() {
        return conteudo.size();
    }

    @Override
    public int getColumnCount() {
        return colunas.length;
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        switch(columnIndex){
            case HORARIO:
                return conteudo.get(rowIndex)[HORARIO];
            
            case SEGUNDA:
                return conteudo.get(rowIndex)[SEGUNDA];
                
            case TERCA:
                return conteudo.get(rowIndex)[TERCA];
                
            case QUARTA:
                return conteudo.get(rowIndex)[QUARTA];
                
            case QUINTA:
                return conteudo.get(rowIndex)[QUINTA];
                
            case SEXTA:
                return conteudo.get(rowIndex)[SEXTA];
                
            case SABADO:
                return conteudo.get(rowIndex)[SABADO];
                
            default:
                throw new IndexOutOfBoundsException("Não é possivel pegar o valor da coluna desejada");
        }
    }

    @Override
    public String getColumnName(int column) {
        return colunas[column];
    }

    //nenhuma celular vai ser editável
    @Override
    public boolean isCellEditable(int rowIndex, int columnIndex) {
        return false;
    }

    @Override
    public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
        JPanel[] paineis = conteudo.get(rowIndex);
        
        switch(columnIndex){
            case HORARIO:
                paineis[HORARIO] = (JPanel)aValue;
                break;
            
            case SEGUNDA:
                paineis[SEGUNDA] = (JPanel)aValue;
                break;
                
            case TERCA:
                paineis[TERCA] = (JPanel)aValue;
                break;
                
            case QUARTA:
                paineis[QUARTA] = (JPanel)aValue;
                break;
                
            case QUINTA:
                paineis[QUINTA] = (JPanel)aValue;
                break;
                
            case SEXTA:
                paineis[SEXTA] = (JPanel)aValue;
                break;
                
            case SABADO:
                paineis[SABADO] = (JPanel)aValue;
                break;
                
            default:
                throw new IndexOutOfBoundsException("Não é possivel pegar o valor da coluna desejada");
        }
        
        fireTableCellUpdated(rowIndex, columnIndex);
    }

    //TODAS AS CELULAS SERÃO JPANEL
    @Override
    public Class<?> getColumnClass(int columnIndex) {
        return JPanel.class;
    }
    
    public void preecherCoresTabela(Date dia){
        preencherListaConteudo();
        DateTime d = new DateTime(dia.getTime());
        DateTime[] diasSemana = new DateTime[6];
        
        //pega os dia da semana de uma determinada data (dias de segunda a sábado)
        diasSemana[0] = d.withDayOfWeek(DateTimeConstants.MONDAY);
        diasSemana[0] = new DateTime(diasSemana[0].year().get(), diasSemana[0].monthOfYear().get(), diasSemana[0].dayOfMonth().get(), 0, 0, 0);
        
        diasSemana[1] = d.withDayOfWeek(DateTimeConstants.TUESDAY);
        diasSemana[1] = new DateTime(diasSemana[1].year().get(), diasSemana[1].monthOfYear().get(), diasSemana[1].dayOfMonth().get(), 0, 0, 0);
        
        diasSemana[2] = d.withDayOfWeek(DateTimeConstants.WEDNESDAY);
        diasSemana[2] = new DateTime(diasSemana[2].year().get(), diasSemana[2].monthOfYear().get(), diasSemana[2].dayOfMonth().get(), 0, 0, 0);
        
        diasSemana[3] = d.withDayOfWeek(DateTimeConstants.THURSDAY);
        diasSemana[3] = new DateTime(diasSemana[3].year().get(), diasSemana[3].monthOfYear().get(), diasSemana[3].dayOfMonth().get(), 0, 0, 0);
        
        diasSemana[4] = d.withDayOfWeek(DateTimeConstants.FRIDAY);
        diasSemana[4] = new DateTime(diasSemana[4].year().get(), diasSemana[4].monthOfYear().get(), diasSemana[4].dayOfMonth().get(), 0, 0, 0);
        
        diasSemana[5] = d.withDayOfWeek(DateTimeConstants.SATURDAY);
        diasSemana[5] = new DateTime(diasSemana[5].year().get(), diasSemana[5].monthOfYear().get(), diasSemana[5].dayOfMonth().get(), 0, 0, 0);
        
        //pesquiso na lista de sessões se há horário a serem preenchidos na tabela, ou seja, se alguma data estão contida no vetor diasSemana
        for(Sessao item: funcionario.getListaSessoes()){
            DateTime dataSessao = new DateTime(item.getDtSessao());
            
            for(int i=0; i<diasSemana.length; i++){
                if(Days.daysBetween(dataSessao, diasSemana[i]).getDays() == 0){
                    //caso conter, eu verifico qual a hora e quantos quadros devem preenchidos
                    int qtdQuadros = qtdQuadroAPreencher(item.getTratamento().getTempo());
                    int[] posicaoTabela = posicaoTabela(item.getHorario());
                    Color cor = determinarCor(item.getTratamento(), item.getHorario());
                    repaintPanel(qtdQuadros, posicaoTabela, i, cor);
                }
            }
        }
    }
    
    public static int qtdQuadroAPreencher(Date horario){
        int qtd = 0;
        try {
            
            DateTime h = new DateTime(horario.getTime());
            DateFormat format = DateFormat.getTimeInstance(DateFormat.SHORT, new Locale("pt", "BR"));
            
            DateTime inicio = new DateTime(format.parse("00:00").getTime());
            String sInicio = format.format(new Date(inicio.getMillis()));
            String sHorario = format.format(new Date(h.getMillis()));
            while(!sInicio.equals(sHorario)){
                qtd++;
                inicio = inicio.plusMinutes(30);
                
                sInicio = format.format(new Date(inicio.getMillis()));
                sHorario = format.format(new Date(h.getMillis()));
            }
        } catch (ParseException ex) {
            System.out.println("erro: " + ex.getMessage());
            ex.printStackTrace();
        }
        
        return qtd;
    }
    
    public static int[] posicaoTabela(Date horario){
        int[] retorno = new int[2];
        int qtd = 0; 
        try {
            
            DateTime h = new DateTime(horario.getTime());
            DateFormat format = DateFormat.getTimeInstance(DateFormat.SHORT, new Locale("pt", "BR"));
            
            DateTime inicio = new DateTime(format.parse("08:00").getTime());
            String sInicio = format.format(new Date(inicio.getMillis()));
            String sHorario = format.format(new Date(h.getMillis()));
            
            while(!sInicio.equals(sHorario)){
                qtd++;
                inicio = inicio.plusMinutes(30);
                
                sInicio = format.format(new Date(inicio.getMillis()));
                sHorario = format.format(new Date(h.getMillis()));
            }
            
            retorno[0] = qtd/2;
            if(qtd % 2 == 0) retorno[1] = 0;
            else retorno[1] = 1;
            
        } catch (ParseException ex) {
            System.out.println("erro: " + ex.getMessage());
            ex.printStackTrace();
        }
        
        return retorno;
    }
    
    public Color determinarCor(Tratamento tratamento, Date horario){
        System.out.println("tipo: " + tratamento.getTipoTratamento().getIdTipoTratamento());
        switch(tratamento.getTipoTratamento().getIdTipoTratamento()){
            case 1: return new Color(0, 153, 255);
            
            case 2:
                //se for pilates, verifica se tem vaga ou não
                if(persisteSessao.retornarSessoesPeloHorario(horario).size() < 3){
                    return new Color(153, 153, 0);
                }else{
                    return new Color(0, 102, 102);
                }
                
            case 3: return new Color(0, 102, 153);
            case 4: return new Color(255, 102, 102);
            default: return new Color(240, 240, 240);
        }
    }
    
    public void repaintPanel(int qtdQuadros, int[] posicaoLinha, int posicaoColuna, Color cor){
        int atual = posicaoLinha[1];
        int aux = 0;
        int desenhandos = 0;
        while(desenhandos < qtdQuadros){
            JPanel[] paineis = conteudo.get(posicaoLinha[0] + aux);
            
            if(atual == 1){
                paineis[posicaoColuna+1] = new PanelPersonalizado(paineis[posicaoColuna+1], 1, 1, cor);
                //desenha 1, posicao 1
                aux++;
                atual = 0;
                desenhandos++;
            }else if(atual == 0){
                if((qtdQuadros - desenhandos) > 1){
                    paineis[posicaoColuna+1] = new PanelPersonalizado(paineis[posicaoColuna+1], 2, 0, cor);
                    aux++;
                    desenhandos+=2;
                }else{
                    paineis[posicaoColuna+1] = new PanelPersonalizado(paineis[posicaoColuna+1], 1, 0, cor);
                    
                    //desenha 1 posicao 0
                    atual++;
                    desenhandos++;
                }
            }
            //System.out.println("panel: " + paineis[posicaoColuna+1]);
            fireTableDataChanged();
        }
    }
    
    
    public void atualizarJPanels(){
        for(JPanel[] item: conteudo){
            for(JPanel panel: item){
                System.out.println("panel: " + panel);
            }
        }
    }
    
}
